﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

namespace HDJ.Framework.Core
{
    public static class TableUtils
    {
        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="strData"></param>
        /// <returns></returns>
        public static TableData TableStringToTableData(string strData)
        {
            //分割数据
            //回车换行
            string[] temp0 = strData.Split(new string[] { "\r\n" }, StringSplitOptions.None);

            string[][] configDatas = new string[temp0.Length][];

            for (int i = 0; i < temp0.Length; i++)
            {
                //制表符
                configDatas[i] = temp0[i].Split(new char[] { '\t' });
            }

            TableData tableConfigData = new TableData();

            if (configDatas.Length > 0)
                tableConfigData.description = configDatas[0][0];
            if (configDatas.Length < 5)
                return tableConfigData;
            //转换成字段描述信息
            for (int j = 0; j < configDatas[4].Length; j++)
            {
                string fieldName = configDatas[3][j];
                string typeFullName = configDatas[1][j];
                string textData = configDatas[4][j];
                TableTypeData typeData = ParseTableTypeData(typeFullName);

                TableFieldInfo info = new TableFieldInfo();
                info.name = fieldName;
                info.tag = typeData.tag;
                info.fieldType = TableTypeSupportController.Instance.GetTableType(typeData);// TableUtils.Type2ConfigFieldValueType(t);
                info.defultValue = TableTypeSupportController.Instance.TableStringData2Value(info.fieldType, textData);// TableUtils.TableStringData2Value(t, textData);
                info.description = configDatas[2][j];
                tableConfigData.fieldInfos.Add(fieldName, info);

            }
            List<TableFieldInfo> fieldInfos = new List<TableFieldInfo>(tableConfigData.fieldInfos.Values);
            //转换成格子数据
            for (int i = 5; i < configDatas.Length; i++)
            {
                string key = "";
                Dictionary<string, object> values = new Dictionary<string, object>();
                for (int j = 0; j < configDatas[i].Length; j++)
                {
                    string valueStr = configDatas[i][j];
                    TableFieldInfo info = fieldInfos[j];
                    object value = null;

                    Type type = info.fieldType;// TableFieldType2Type(info.fieldType, info.enumType);
                    value = TableTypeSupportController.Instance.TableStringData2Value(type, valueStr);
                    if (j == 0)
                    {
                        key = value.ToString();
                    }
                    values.Add(info.name, value);
                }

                tableConfigData.datas.Add(key, values);
            }

            return tableConfigData;
        }

        private static TableTypeData ParseTableTypeData(string text)
        {
            string data = text;
            string dataType = null;
            string typeCategory = null;
            string tag = null;
            if (data.Contains("|")&&data.Contains("@"))
            {
                {
                    int index0 = data.IndexOf('|');
                    dataType = data.Substring(0, index0);
                    data = data.Remove(0, index0 + 1);
                }
                {
                    int index0 = data.IndexOf('@');
                   
                    typeCategory = data.Substring(0, index0);
                    
                    data = data.Remove(0, index0 + 1);
                }
                tag = data;
                
            }
            else if (data.Contains("|") )
            {
                    int index0 = data.IndexOf('|');
                    dataType = data.Substring(0, index0);
                    data = data.Remove(0, index0 + 1);

                typeCategory = data;

            }
          else  if (data.Contains("@"))
            {
                int index0 = data.IndexOf('@');
               
                    dataType = data.Substring(0, index0);

                data = data.Remove(0, index0 + 1);
                tag = data;
            }
            else
            {
                dataType = data;
            }
            Debug.Log("text:" + text + " dataType:" + dataType + " typeCategory:" + typeCategory+ " tag:"+ tag);
            return new TableTypeData(dataType, typeCategory, tag);
        }
        public static TableBase[] CreateTableClass(TableData data, Type type)
        {
            List<TableBase> tableClassArray = new  List<TableBase>();
            //转换成TableConfigBase类数据
            if (type != null)
            {
                foreach (var lineData in data.datas.Values)
                {
                    TableBase instance = Activator.CreateInstance(type) as TableBase;
                    foreach (var item in lineData)
                    {
                        FieldInfo f = type.GetField(item.Key);
                        if (f != null)
                        {
                            f.SetValue(instance, item.Value);
                        }
                    }
                    tableClassArray.Add(instance);
                }
               
                
            }
            return tableClassArray.ToArray();
        }
        /// <summary>
        /// 创建 表的Class 数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T[] CreateTableClass<T>(TableData data) where T : TableBase
        {
            List<T> tableClassArray = new List<T>();
            Type type = typeof(T);
            //转换成TableConfigBase类数据
            if (type != null)
            {
                foreach (var lineData in data.datas.Values)
                {
                    T instance = Activator.CreateInstance(type) as T;
                    foreach (var item in lineData)
                    {
                        FieldInfo f = type.GetField("m_"+ item.Key, BindingFlags.Instance | BindingFlags.NonPublic);
                        if (f != null)
                        {
                            f.SetValue(instance, item.Value);
                        }
                    }
                    tableClassArray.Add(instance);
                }


            }
            return tableClassArray.ToArray();
        }
        /// <summary>
        /// 将表格信息转换成文本信息便于保存成文件
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public static string TableData2Text(TableData info)
        {
            if (string.IsNullOrEmpty(info.description))
                info.description = "配置文件描述";
            string tableText = info.description;
            tableText += "\r\n";

            List<TableFieldInfo> list = new List<TableFieldInfo>(info.fieldInfos.Values);
            for (int i = 0; i < list.Count; i++)
            {
                TableFieldInfo f = list[i];
                TableTypeData typeData = TableTypeSupportController.Instance.GetTypeData(f.fieldType, f.tag);
                Debug.Log("TableTypeData:" + typeData);
                tableText += typeData.dataType;
                if (!string.IsNullOrEmpty(typeData.typeCategory))
                {
                    tableText += "|" + typeData.typeCategory;
                }
                if (!string.IsNullOrEmpty(typeData.tag))
                {
                    tableText += "@" + f.tag;
                }

                if (i == list.Count - 1)
                    tableText += "\r\n";
                else
                    tableText += "\t";
            }

            for (int i = 0; i < list.Count; i++)
            {
                tableText += list[i].description;
                if (i == list.Count - 1)
                    tableText += "\r\n";
                else
                    tableText += "\t";
            }

            for (int i = 0; i < list.Count; i++)
            {
                tableText += list[i].name;
                if (i == list.Count - 1)
                    tableText += "\r\n";
                else
                    tableText += "\t";
            }

            for (int i = 0; i < list.Count; i++)
            {
                tableText += TableTypeSupportController.Instance. ObjectValue2TableString(list[i].defultValue);
                if (i < list.Count - 1)
                    tableText += "\t";
            }
            if (info.datas.Count > 0)
            {
                tableText += "\r\n";
                int j = 0;
                foreach (var lineData in info.datas.Values)
                {
                    int i = 0;
                    foreach (var item in info.fieldInfos.Keys)
                    {
                        object v = lineData[item];
                        if (v == null)
                        {
                            tableText += "";
                        }
                        else
                        {
                            tableText += TableTypeSupportController.Instance. ObjectValue2TableString(v);
                        }
                        if (i < list.Count - 1)
                        {
                            tableText += "\t";
                            i++;
                        }
                    }
                    Debug.Log("End");
                    if (j < info.datas.Count - 1)
                    {
                        tableText += "\r\n";
                        j++;
                    }
                }
            }
            Debug.Log(tableText);
            return tableText;


        }
        ///// <summary>
        ///// 将类型转换成表格文本上的类型关键字
        ///// </summary>
        ///// <param name="t"></param>
        ///// <returns></returns>
        //private static string TypeChangeToKeyWord(Type t)
        //{
        //    string typeName = t.FullName;

        //    if (typeof(int).FullName == typeName)
        //        return "int";
        //    else if (typeof(float).FullName == typeName)
        //        return "float";
        //    else if (typeof(bool).FullName == typeName)
        //        return "bool";
        //    else if (typeof(string).FullName == typeName)
        //        return "string";
        //    else if (typeof(Vector3).FullName == typeName)
        //        return "Vector3";
        //    else if (typeof(Vector2).FullName == typeName)
        //        return "Vector2";
        //    else if (typeof(Vector3[]).FullName == typeName)
        //        return "Vector3[]";
        //    else if (typeof(Vector2[]).FullName == typeName)
        //        return "Vector2[]";
        //    else if (typeof(int[]).FullName == typeName)
        //        return "int[]";
        //    else if (typeof(float[]).FullName == typeName)
        //        return "float[]";
        //    else if (typeof(bool[]).FullName == typeName)
        //        return "bool[]";
        //    else if (typeof(string[]).FullName == typeName)
        //        return "string[]";
        //    else if (t.IsEnum)
        //    {
        //        typeName = t.FullName;
        //    }


        //    return typeName;
        //}
        /// <summary>
        /// Type转换成ConfigFieldValueType
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        //public static TableFieldType Type2ConfigFieldValueType(Type t)
        //{
        //    if (typeof(int) == t)
        //        return TableFieldType.Int;
        //    else if (typeof(float) == t)
        //        return TableFieldType.Float;
        //    else if (typeof(bool) == t)
        //        return TableFieldType.Bool;
        //    else if (typeof(string) == t)
        //        return TableFieldType.String;
        //    else if (typeof(Vector3) == t)
        //        return TableFieldType.Vector3;
        //    else if (typeof(Vector2) == t)
        //        return TableFieldType.Vector2;
        //    else if (typeof(Vector3[]) == t)
        //        return TableFieldType.Vector3_Array;
        //    else if (typeof(Vector2[]) == t)
        //        return TableFieldType.Vector2_Array;
        //    else if (typeof(int[]) == t)
        //        return TableFieldType.Int_Array;
        //    else if (typeof(float[]) == t)
        //        return TableFieldType.Float_Array;
        //    else if (typeof(bool[]) == t)
        //        return TableFieldType.Bool_Array;
        //    else if (typeof(string[]) == t)
        //        return TableFieldType.String_Array;
        //    else if (t.IsEnum)
        //        return TableFieldType.Enum;
        //    return TableFieldType.Int;
        //}
        /// <summary>
        ///TableFieldType转换成类型
        /// </summary>
        /// <param name="vType"></param>
        /// <returns></returns>
        //public static Type TableFieldType2Type(TableFieldType vType,string enumType)
        //{
        //    switch (vType)
        //    {
        //        case TableFieldType.Int:
        //            return typeof(int);
        //        case TableFieldType.Float:
        //            return typeof(float);
        //        case TableFieldType.Bool:
        //            return typeof(bool);
        //        case TableFieldType.String:
        //            return typeof(string);
        //        case TableFieldType.Enum:
        //          return  ReflectionUtils.GetTypeByTypeFullName(enumType,false);  
        //        case TableFieldType.Vector2:
        //            return typeof(Vector2);
        //        case TableFieldType.Vector3:
        //            return typeof(Vector3);
        //        case TableFieldType.Int_Array:
        //            return typeof(int[]);
        //        case TableFieldType.Float_Array:
        //            return typeof(float[]);
        //        case TableFieldType.Bool_Array:
        //            return typeof(bool[]);
        //        case TableFieldType.String_Array:
        //            return typeof(string[]);
        //        case TableFieldType.Vector2_Array:
        //            return typeof(Vector2[]);
        //        case TableFieldType.Vector3_Array:
        //            return typeof(Vector3[]);
        //    }

        //    return null;
        //}
        ///// <summary>
        ///// 将object数据转换成特定的string 
        ///// </summary>
        ///// <param name="value"></param>
        ///// <returns></returns>
        //public static string ObjectValue2TableString(object value)
        //{
        //    string result = "";
        //    if (null == value)
        //        return "";

        //    Type t = value.GetType();
        //    string typeName = t.FullName;

        //    if (!t.IsArray)
        //    {
        //        result = value.ToString();
        //    }
        //    else 
        //    {
        //        Type itemType = t.GetElementType();
        //        PropertyInfo pro = t.GetProperty("Length");
        //        int count = (int)pro.GetValue(value, null);
        //        MethodInfo methodInfo = t.GetMethod("GetValue", new Type[] { typeof(int) });
        //        if (itemType.IsPrimitive || itemType.FullName == typeof(string).FullName)
        //        {
        //            result = JsonUtils.ToJson(value);
        //        }
        //        else if (typeof(Vector3).FullName == itemType.FullName|| typeof(Vector2).FullName == itemType.FullName)
        //        {
        //            for (int i = 0; i < count; i++)
        //            {
        //                object da = methodInfo.Invoke(value, new object[] { i });
        //                result += da.ToString();
        //                if(i<(count-1))
        //                result += ",";
        //            }
        //        }

        //    }
        //    return result;

        //}
        ///// <summary>
        ///// 表格里的文本数据转换成对应的Value值
        ///// </summary>
        ///// <param name="type"></param>
        ///// <param name="data">当为空时返回类型默认值</param>
        ///// <returns></returns>
        //public static object TableStringData2Value(Type type, string data)
        //{
        //    object obj = null;
        //    bool isDataEmpty = string.IsNullOrEmpty(data);
        //    if (type.IsEnum)
        //    {
        //        if (isDataEmpty)
        //        {
        //            Array array = Enum.GetValues(type);
        //            obj = array.GetValue(0);
        //        }
        //        else
        //        {
        //            obj = Enum.Parse(type, data);
        //        }
        //    }
        //   else if (type == typeof(int))
        //    {
        //        obj = (isDataEmpty) ? 0 : int.Parse(data);
        //    }
        //    else if (type == typeof(float))
        //    {
        //        obj = (isDataEmpty) ? 0f : float.Parse(data);
        //    }
        //    else if (type == typeof(bool))
        //    {
        //        obj = (isDataEmpty) ? false : bool.Parse(data);
        //    }
        //    else if (type == typeof(string))
        //    {
        //        obj = (isDataEmpty) ? "" : data;
        //    }
        //    else if (type == typeof(Vector2))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = StringData2Vector(data); ;
        //        }
        //        else
        //        {
        //            obj = Vector2.zero;
        //        }
        //    }
        //    else if (type == typeof(Vector3))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = StringData2Vector(data); ;
        //        }
        //        else
        //        {
        //            obj = Vector3.zero;
        //        }
        //    }
        //    else if (type == typeof(int[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = JsonUtils.FromJson(type, data);
        //        }
        //        else
        //        {
        //            obj = new int[0];
        //        }
        //    }
        //    else if (type == typeof(float[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = JsonUtils.FromJson(type, data);
        //        }
        //        else
        //        {
        //            obj = new float[0];
        //        }
        //    }
        //    else if (type == typeof(bool[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = JsonUtils.FromJson(type, data);
        //        }
        //        else
        //        {
        //            obj = new bool[0];
        //        }
        //    }
        //    else if (type == typeof(string[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            obj = JsonUtils.FromJson(type, data);
        //        }
        //        else
        //        {
        //            obj = new string[0];
        //        }
        //    }
        //    else if (type == typeof(Vector2[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            string[] temp0 = StringSplitInStartAndEndChar(data, '(', ')');
        //            List<Vector2> v2List = new List<Vector2>();
        //            for (int x = 0; x < temp0.Length; x++)
        //            {
        //                Vector2 v2 = (Vector2)StringData2Vector(temp0[x]);
        //                v2List.Add(v2);
        //            }
        //            obj = v2List.ToArray();
        //        }
        //        else
        //        {
        //            obj = new Vector2[0];
        //        }
        //    }
        //    else if (type == typeof(Vector3[]))
        //    {
        //        if (!isDataEmpty)
        //        {
        //            string[] temp0 = StringSplitInStartAndEndChar(data, '(', ')');
        //            List<Vector3> v3List = new List<Vector3>();
        //            for (int x = 0; x < temp0.Length; x++)
        //            {
        //                Vector3 v3 = (Vector3)StringData2Vector(temp0[x]);
        //                v3List.Add(v3);
        //            }
        //            obj = v3List.ToArray();
        //        }
        //        else
        //        {
        //            obj = new Vector3[0];
        //        }
        //    }
        //    return obj;
        //}
        ///// <summary>
        ///// 表格里的文本数据转换成对应的Value值
        ///// </summary>
        ///// <param name="fieldType"></param>
        ///// <param name="data"></param>
        ///// <returns></returns>
        //public static Type StringFieldType2Type(string fieldType,string enumType)
        //{
        //    Type type = null;
        //    try
        //    {
        //        if (fieldType == "int")
        //        {
        //            type = typeof(int);
        //        }
        //        else if (fieldType == "float")
        //        {
        //            type = typeof(float);
        //        }
        //        else if (fieldType == "bool")
        //        {
        //            type = typeof(bool);
        //        }
        //        else if (fieldType == "string")
        //        {
        //            type = typeof(string);
        //        }
        //        else if (fieldType == "Vector3")
        //        {
        //            type = typeof(UnityEngine.Vector3);
        //        }
        //        else if (fieldType == "Vector2")
        //        {
        //            type = typeof(UnityEngine.Vector2);
        //        }
        //        else if (fieldType == "Vector3[]")
        //        {
        //            type = typeof(UnityEngine.Vector3[]);
        //        }
        //        else if (fieldType == "Vector2[]")
        //        {
        //            type = typeof(UnityEngine.Vector2[]);
        //        }
        //        else if (fieldType == "int[]")
        //        {
        //            type = typeof(int[]);
        //        }
        //        else if (fieldType == "float[]")
        //        {
        //            type = typeof(float[]);
        //        }
        //        else if (fieldType == "bool[]")
        //        {
        //            type = typeof(bool[]);
        //        }
        //        else if (fieldType == "string[]")
        //        {
        //            type = typeof(string[]);
        //        }
        //        else if(fieldType == "enum")
        //        {
        //             type = ReflectionUtils.GetTypeByTypeFullName(enumType);
        //        }
        //        else
        //        {
        //            Debug.LogError("不支持的类型：" + fieldType + " enumType:" + enumType  );
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        Debug.LogError("StringData2Type :" + fieldType +" enumType:"+enumType+ "\n" + e);
        //        return null;
        //    }
        //    if (type == null)
        //    {
        //        Debug.LogError("转换Type失败：" + fieldType + " enumType:" + enumType);
        //    }
        //    return type;
        //}
        /// <summary>
        /// 字符串分割
        /// </summary>
        /// <param name="data"></param>
        /// <param name="startChar">开始分割的标记字符串</param>
        /// <param name="endChar">结束分割的标记字符串</param>
        /// <returns></returns>
        public static string[] StringSplitInStartAndEndChar(string data, char startChar, char endChar)
        {
            char[] charArray;
            List<string> tList = new List<string>();
            string tempData = data;
            bool isEnd = false;

            while (!isEnd)
            {
                int startIndex = 0;
                int endIndex = 0;
                isEnd = true;
                bool startCheckEnd = false;
                charArray = tempData.ToCharArray();
                for (int i = 0; i < charArray.Length; i++)
                {
                    if (startCheckEnd && charArray[i] == endChar)
                    {
                        endIndex = i;
                        isEnd = false;
                        break;
                    }
                    if (!startCheckEnd && charArray[i] == startChar)
                    {
                        startIndex = i;
                        startCheckEnd = true;
                    }
                }
                if (!isEnd)
                {
                    string tempStr1 = tempData.Substring(startIndex, endIndex - startIndex + 1);
                    tempStr1 = tempStr1.Replace(startChar.ToString(), "");
                    tempStr1 = tempStr1.Replace(endChar.ToString(), "");
                    tList.Add(tempStr1);
                    tempData = tempData.Remove(startIndex, endIndex - startIndex + 1);
                    // Debug.Log("tempStr1 : " + tempStr1 + " __tempData : " + tempData);
                }

            }

            return tList.ToArray();

        }
        /// <summary>
        /// 把字符串解析成解析vector2,3
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static object StringData2Vector(string data)
        {
            data = data.Replace("(", "");
            data = data.Replace(")", "");
            string[] temp = data.Split(new char[] { ',' });
            float[] temp1 = new float[temp.Length];
            for (int i = 0; i < temp.Length; i++)
            {
                temp1[i] = float.Parse(temp[i]);
            }
            if (temp.Length > 2)
            {
                Vector3 v3 = new Vector3(temp1[0], temp1[1], temp1[2]);
                return v3;
            }
            else
            {
                Vector2 v2 = new Vector2(temp1[0], temp1[1]);
                return v2;
            }
        }

        public static bool ValueEquals(object v0,object v1)
        {
            if (v0 == null && v1 == null)
                return true;
           else if ((v0 == null && v1 != null) || (v0 != null && v1 == null))
                return false;
            return v0.Equals(v1);
        }

    }
}
